/**
 * This file is Copyright © 2008 Software Craftsmen Limited. All Rights Reserved.
 */
package com.softwarecraftsmen.archivers.zip.zipEntryAndData;

import com.softwarecraftsmen.inputStreamReaders.CopyingInputStreamReader;
import com.softwarecraftsmen.inputStreamReaders.InputStreamReader;
import org.jetbrains.annotations.NotNull;

import java.io.BufferedInputStream;
import java.io.IOException;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
import java.util.zip.ZipOutputStream;

public class ExistingZipEntryBackedZipEntryAndData implements ZipEntryAndData
{
	private final ZipEntry existingZipEntry;
	private final ZipFile fromExistingZipFile;
	private static final int OneKilobyte = 1024;
	private static final int BufferSize = 8 * OneKilobyte;

	public ExistingZipEntryBackedZipEntryAndData(final @NotNull ZipEntry existingZipEntry, final @NotNull ZipFile fromExistingZipFile)
	{
		this.existingZipEntry = existingZipEntry;
		this.fromExistingZipFile = fromExistingZipFile;
	}

	@SuppressWarnings({"ThrowFromFinallyBlock"})
	public void write(final @NotNull ZipOutputStream outputStream) throws IOException
	{
		outputStream.putNextEntry(new ConvenientZipEntry(existingZipEntry.getName(), existingZipEntry.getTime()));
		readData(new CopyingInputStreamReader(outputStream));
		outputStream.closeEntry();
	}

	@NotNull
	public String pathNameInsideZip()
	{
		return existingZipEntry.getName();
	}

	@NotNull
	@SuppressWarnings({"ThrowFromFinallyBlock"})
	public <T> T readData(final @NotNull InputStreamReader<T> inputStreamReader) throws IOException
	{
		final BufferedInputStream inputStream = new BufferedInputStream(fromExistingZipFile.getInputStream(existingZipEntry), BufferSize);
		boolean exceptionThrown = true;
		try
		{
			final T t = inputStreamReader.read(BufferSize, inputStream);
			exceptionThrown = false;
			return t;
		}
		finally
		{
			try
			{
				inputStream.close();
			}
			catch (IOException e)
			{
				if (!exceptionThrown)
				{
					throw e;
				}
			}
		}
	}
}
